/* ==============================================================================
 * www.sucaijiayuan.com
 * 
 * modifed by zengjing at 2015.04.03
 * 添加最大值限制，添加值改变事件
 */
;(function ($) {
  $.fn.spinner = function (opts) {
	var defaults = {size: '', value:0, min:0, max: 0, onChanged: function(_this, value, _v){}}
    var options = $.extend(defaults, opts)
	  
    return this.each(function () {
     
      var keyCodes = {up:38, down:40}
      var container = $('<div></div>')
      container.addClass('spinner' + options.size)
      var textField = $(this).addClass('value').attr('maxlength', '2').val(options.value)
        .bind('keyup paste change', function (e) {
          var field = $(this)
          if (e.keyCode == keyCodes.up) changeValue(1)
          else if (e.keyCode == keyCodes.down) changeValue(-1)
          else if (getValue(field) != container.data('lastValidValue')) validateAndTrigger(field)
        })
      textField.wrap(container)

      var increaseButton = $('<button class="increase"></button>').click(function () { changeValue(1)})
      var decreaseButton = $('<button class="decrease"></button>').click(function () { changeValue(-1) })

      validate(textField)
      container.data('lastValidValue', options.value)
      textField.before(decreaseButton)
      textField.after(increaseButton)

      function changeValue(delta) {		
        textField.val(getValue() + delta)
        validateAndTrigger(textField)

		options.onChanged(textField, getValue(), delta);
		
		e = window.event || e;
		if (e.stopPropagation) {
			e.stopPropagation();
		} else {
			e.cancelBubble = true;
		}
      }

      function validateAndTrigger(field) {
        clearTimeout(container.data('timeout'))
        var value = validate(field)
        if (!isInvalid(value)) {
          textField.trigger('update', [field, value])
        }
      }

      function validate(field) {
        var value = getValue()

		if (value == options.min && value == options.max)
		{
			decreaseButton.attr('disabled', 'disabled')
			increaseButton.attr('disabled', 'disabled')
		}
        else if (value <= options.min)
		{ 
			decreaseButton.attr('disabled', 'disabled')
			increaseButton.removeAttr('disabled')
		}
		else if (value >= options.max)
		{
			decreaseButton.removeAttr('disabled')
			
			if (value > options.max)
			{
				value = options.max;
				textField.val(value);
			}
			
			// 默认0为无限制
			if (options.max > 0)
			{
				increaseButton.attr('disabled', 'disabled')
			}
		}
        else 
		{
			decreaseButton.removeAttr('disabled')
			increaseButton.removeAttr('disabled')
		}
		  
        field.toggleClass('invalid', isInvalid(value)).toggleClass('passive', value === 0)

        if (isInvalid(value)) {
          var timeout = setTimeout(function () {
            textField.val(container.data('lastValidValue'))
            validate(field)
          }, 500)
          container.data('timeout', timeout)
        } else {
          container.data('lastValidValue', value)
        }
        return value
      }

      function isInvalid(value) { return isNaN(+value) || value < options.min || value > options.max;}

      function getValue(field) {
        field = field || textField;
        return parseInt(field.val() || 0, 10)
      }
    })
  }
})(jQuery)
